package com.et114.modules.org.services;


import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import java.util.Map;
import java.util.Hashtable;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.et114.core.common.AppContext;
import com.et114.core.control.IAppInitBean;



/** @author guanhw
 * OnLineUserListener类实现HttpSessionBindingListener接口
 * OnLineUserListener类将具有HttpSessionBindingListener接口的特有属性
 * public void valueBound(HttpSessionBindingEvent e)
 * public void valueUnBound(HttpSessionBindingEvent e)
 * OnLineUserListener实现一些方法：获取在线用户数
 * 
 */

public class OnLineUserListener implements HttpSessionBindingListener , IAppInitBean {
	public Log							logger		= LogFactory.getLog ( this.getClass ( ) );
	private  Vector						users		= new Vector ( );
	private  Map						usersCrt	= new Hashtable ( );
	private  Map						usersSessionIds	= new Hashtable ( );
	
	private  Long						delay;
	private  Long						period;
	private  Long						deleyCheck;

	public static  OnLineUserListener getInstance ( ) {
		return ( OnLineUserListener )AppContext.getBean ( "onLineUserListener" ) ; 
	}
	
	
	public int getCount ( ) {
		users.trimToSize ( );//调整Vector users的容量为Vector users的大小
		return users.capacity ( );//返回users的容量
	}
	
	public boolean existUser ( String userName ) {
		users.trimToSize ( );
		boolean existUser = false;
		for ( int i = 0 ; i < users.capacity ( ) ; i ++ ) {
			if ( userName.equals ( ( String ) users.get ( i ) ) ) {
				existUser = true;
				break;
			}
		}
		return existUser;
	}
	
	public boolean deleteUser ( String userName ) {
		users.trimToSize ( );
		if ( existUser ( userName ) ) {
			int currUserIndex = - 1;
			for ( int i = 0 ; i < users.capacity ( ) ; i ++ ) {
				if ( userName.equals ( ( String ) users.get ( i ) ) ) {
					currUserIndex = i;
					break;
				}
			}
			if ( currUserIndex != - 1 ) {
				users.remove ( currUserIndex );
				users.trimToSize ( );
				usersCrt.remove (  userName  ) ;
				return true;
			}
		}
		return false;
	}
	
	public Vector getOnLineUser ( ) {
		return users;
	}
	
	public void valueBound ( HttpSessionBindingEvent e ) {
		users.trimToSize ( );
		//if ( ! existUser ( e.getName ( ) ) ) {
			users.add ( e.getName ( ) );
			usersCrt.put ( e.getName ( ) , String.valueOf ( System.currentTimeMillis ( ) ) ) ;
		//} else {
		//}
		usersSessionIds.put ( e.getName ( ) , e.getSession ( ).getId ( ) ) ;
	}
	
	public void valueUnbound ( HttpSessionBindingEvent e ) {
		users.trimToSize ( );
		String userName = e.getName ( );
		deleteUser ( userName );
		usersSessionIds.remove ( userName ) ;
	}
	
	
	public void updateUser( String loginName  ) {
		usersCrt.put ( loginName  , String.valueOf ( System.currentTimeMillis ( ) ) ) ;
	}
	
    class ListenerTimer extends TimerTask {
	    long ms = ( deleyCheck == null ? 5000 : deleyCheck.longValue ( ) );
        public  void clearLms() {
                for ( int i = 0 ; i < users.size() ; i ++ ) {
                	    String loginName = users.get ( i ).toString ( ) ; 
                        long cut = System.currentTimeMillis();
                        long ut = Long.parseLong (  usersCrt.get ( loginName ).toString ( ) ) ;
                        if ( cut - ut > ms ){
                        	users.remove( i );
                        	usersCrt.remove ( loginName ) ;
                        }
                }
        }


        public void run() {
                clearLms();
        }
    }

	public void timeStart(  ){
		if ( delay == null ) delay = new Long( 2000 ) ;
		if ( period == null ) period = new Long( 2000 ) ;
		java.util.Timer  timer  = new Timer();
	    timer.schedule( new ListenerTimer() , delay.longValue ( ) , period.longValue ( ) );
	}

	public void init ( ) throws Exception {

	}	

	public Map getUsersSessionIds ( ) {
		return usersSessionIds;
	}

	public void setUsersSessionIds ( Map usersSessionIds ) {
		this.usersSessionIds = usersSessionIds;
	}

	public Long getDelay ( ) {
		return delay;
	}
	public void setDelay ( Long delay ) {
		this.delay = delay;
	}
	public Long getPeriod ( ) {
		return period;
	}
	public void setPeriod ( Long period ) {
		this.period = period;
	}
	public Long getDeleyCheck ( ) {
		return deleyCheck;
	}
	public void setDeleyCheck ( Long deleyCheck ) {
		this.deleyCheck = deleyCheck;
	}
}
